package org.wannatrak.android.executions;

import android.content.BroadcastReceiver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import org.wannatrak.android.entity.Track;
import org.wannatrak.android.entity.TrackStatus;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: Maksim Tulupov maxtulupov@gmail.com
 * @Date: $Date: 2011-11-29 08:41:22 +0000 (Tue, 29 Nov 2011) $ 11:56 AM
 * @version: $Revision: 33 $
 * @id: $Id: GPSBroadcastReceiver.java 33 2011-11-29 08:41:22Z maxtulupov@gmail.com $
 */
public class GPSBroadcastReceiver extends BroadcastReceiver {

    private Context context;

    private static List<LocationListener> listeners = new ArrayList<LocationListener>();

    @Override
    public void onReceive(Context context, Intent intent) {
        this.context = context;
        final LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        if (isStopTrack(intent)) {
            Log.e(getClass().getSimpleName(), "stop location listeners");
            stopListeners(locationManager);
        } else {
            List<String> providers = locationManager.getProviders(true);
            if (providers.contains(LocationManager.GPS_PROVIDER)) {
                Log.e(getClass().getSimpleName(), "GPS provider found");
                listeners.add(new WannaTrakLocationListener(locationManager, true));
            }
        }
    }

    private boolean isStopTrack(Intent intent) {
        return intent.getBooleanExtra("stopTrack", false);
    }

    private void stopListeners(LocationManager locationManager) {
        Log.e(getClass().getSimpleName(), "listeners size = " + listeners.size());
        for (LocationListener ll : listeners) {
            locationManager.removeUpdates(ll);
        }
        listeners.clear();
    }

    private void insertLocation(Location location) {
        Log.e(getClass().getSimpleName(), "location changed");
        try {
            Log.e(getClass().getSimpleName(), "location created ");
            ContentValues cv = new ContentValues();
            cv.put(Track.CREATE_DATE, System.currentTimeMillis());
            cv.put(Track.LATITUDE, location.getLatitude());
            cv.put(Track.LONGITUDE, location.getLongitude());
            cv.put(Track.ACCURACY, location.getAccuracy());
            cv.put(Track.ALTITUDE, location.getAltitude());
            cv.put(Track.SPEED, location.getSpeed());
            cv.put(Track.BEARING, location.getBearing());
            cv.put(Track.STATUS, TrackStatus.CREATED.getId());
            context.getContentResolver().insert(Track.CONTENT_URI, cv);
            Log.e(getClass().getSimpleName(), "location saved in db");
        } catch (Exception e) {
            Log.e(getClass().getSimpleName(), "error save location in DB", e);
        }
    }

    private class WannaTrakLocationListener implements LocationListener {

        private LocationManager locationManager;

        private WannaTrakLocationListener(LocationManager locationManager, boolean gps) {
            this.locationManager = locationManager;
            if (gps) {
                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0.0f, this);
            } else {
                locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0.0f, this);
            }
        }

        public void onLocationChanged(Location location) {
            try {
                insertLocation(location);
            } finally {
                locationManager.removeUpdates(this);
                listeners.remove(this);
                Log.e(getClass().getSimpleName(), "stop location listener. I works normally");
            }
        }

        public void onStatusChanged(String s, int i, Bundle bundle) {
        }

        public void onProviderEnabled(String s) {
        }

        public void onProviderDisabled(String s) {
        }
    }
}
